<?php

/**
 * These libraries are required to talk to Evernote and access their data.
 * boostrap.php sets up class autoloader for all the Evernote libraries. If you're
 * already using class autoloader, see bootstrap.php for information on how to
 * properly implement it.
 *
 * OAuth_SimpleRequest is required for establishing OAuth sessions.
 *
 */
require_once( dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "bootstrap.php");
require_once("OAuth/SimpleRequest.php");

/**
 * Basic mechanism for overriding configuration define's.
 *
 */
if ( is_file( dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "localDefines.php"))
	require_once( dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "localDefines.php");

/**
 * OAuth Consumer name - typically name of the site that wishes to access Evernote data.
 *
 */
define("consumerName", "Evernote OAuth Test Organization");


/**************** CONFIGURATION ****************/
/**
 * This set of information will be provided to you by Evernote when
 * you register for use of the API.
 *
 */
define("consumerKey", "en-oauth-test");
define("consumerSecret", "0123456789abcdef");
define("spHostname","https://lb.evernote.com");
define("requestTokenUrl", spHostname . "/oauth");
define("accessTokenUrl", spHostname . "/oauth");
define("authorizationUrlBase", spHostname . "/OAuth.action");
define("noteStoreHost", "lb.evernote.com");
define("noteStorePort", "80");
define("noteStoreProto", "https");
define("noteStoreUrl", "edam/note/");


/**************** HELPER FUNCTIONS ****************/
/**
 * Handler for ?action=... requests.
 * Currently handles complete reset of the session.
 *
 * @return void
 */
function doAction() {
	if ( isset($_GET['action'])) {
		switch ($_GET['action']) {
			case 'resetSession':
				resetSession();
				header("Location: " . $_SERVER['SCRIPT_NAME']);
				break;
		}
	}
}
/**
 * OAuth authorization handler. 
 * First checks, if valid OAuth session already exists.
 * If there is no OAuth session, makes a request for RequestToken.
 * If RequestToken already exists, makes a request for AccessToken.
 * 
 * @return void
 */
function doAuth() {
	if (isAuthed()) {
		return;
	} else if ( isset($_SESSION['requestToken'])) {
		getAccessToken();
	} else {
		getRequestToken();
	}
}
/**
 * Convinience method to append global messages (errors) to the session.
 * These are used to notify user of various errors.
 *
 * @param string $message 
 * @param int $code
 */
function raiseAppError($message, $code = 0) {
	if (!hasErrors())
		$_SESSION['app_errors']= array();
	$_SESSION['app_errors'][] = PEAR::raiseError($message, intval($code));
}
/**
 * Checks if there are global messages / errors in the session.
 *
 * @return boolean
 */
function hasErrors() {
	if (isset($_SESSION['app_errors']) && is_array($_SESSION['app_errors']) && count($_SESSION['app_errors']) > 0)
		return true;
	return false;
}
/**
 * Checks if there's an already established OAuth session.
 *
 * @return boolean TRUE if there is an established OAuth session, FALSE otherwise.
 */
function isAuthed() {
	if ( isset($_SESSION['accessToken']) && isset($_SESSION['shardId'])) {
		return true;
	}
	return false;
}
/**
 * Resets current session. This completely invalidates existing OAuth session and wipes any state data.
 *
 */
function resetSession() {
	$_SESSION = array();
}
/**
 * Requests OAuth RequestToken from Evernote and returns it.
 *
 * @return string
 */
function getRequestToken() {
	$oauthRequestor = new OAuth_SimpleRequest(requestTokenUrl, consumerKey, consumerSecret);
	try {
		$oauthRequestor->sendRequest();
		$reply = $oauthRequestor->getResponseStruct();
		if (isset($reply['oauth_token'])) {
			$_SESSION['requestToken'] = $reply['oauth_token'];
		} else {
			raiseAppError("Sorry, having problems talking to Evernote. Please seek guidance with higher authority.");
			return false;
		}
	} catch (HTTP_Exception $e) {
		raiseAppError("Sorry, Evernote service is currently unavailable. Take the red pill!");
		return false;
	}
	return true;
}
/**
 * Requests OAuth AccessToken from Evernote and returns it.
 *
 * @return string
 */
function getAccessToken() {
	if (isAuthed())
		return;
	$oauthRequestor = new OAuth_SimpleRequest(requestTokenUrl, consumerKey, consumerSecret);
	$oauthRequestor->setParameter("oauth_token", $_SESSION['requestToken']);
	try {
		$oauthRequestor->sendRequest();
		$reply = $oauthRequestor->getResponseStruct();
		if (isset($reply['oauth_token']))
			$_SESSION['accessToken'] = $reply['oauth_token'];
		if (isset($reply['edam_shard']))
			$_SESSION['shardId'] = $reply['edam_shard'];
		
		if (!isset($reply['oauth_token']) || !isset($reply['edam_shard'])) {
			raiseAppError("Sorry, having problems talking to Evernote. Please seek guidance with higher authority.");
			return false;
		} else if (isset($_SESSION['requestToken'])) {
			unset($_SESSION['requestToken']);
		}
	} catch (HTTP_Exception $e) {
		if ($oauthRequestor->getResponseCode() == 401) {
			// perhaps requestToken was expired, try to get a new one
			resetSession();
			getRequestToken();
		} else {
			raiseAppError("Sorry, Evernote service is currently unavailable. Take the blue pill!");
		}
		return false;
	}
	return true;
}
/**
 * Returns callback URL. 
 * This URL is passed to Evernote when sending user to authorize their RequestToken.
 * Evernote then returns user, along with authorized RequestToken, back to this URL.
 *
 * @return string
 */
function getCallbackUrl() {
	global $callbackUrl;
	if (empty($callbackUrl)) {
		$callbackUrl = "http://" . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'];
	}
	return $callbackUrl;
}
/**
 * Returns Authorization URL. 
 * Authorization URL is the URL to Evernote's user authorization page.
 *
 * @return string
 */
function getAuthUrl() {
	global $authorizationUrl;
	if (empty($authorizationUrl)) {
		$authorizationUrl = authorizationUrlBase . "?oauth_callback=" .
			rawurlencode(getCallbackUrl()) . "&oauth_token=" .
			$_SESSION['requestToken'];
		$authorizationUrl .= "&format=microclip";	// special page for embedding...
	}
	return $authorizationUrl;
}
/**
 * Fetches and return list of notebooks for authorized Evernote user.
 * 
 * @return array Array of Notebook objects
 */
function getNotebooks() {
	global $notebooks;
	if (empty($notebooks) && isAuthed()) {
		try {
			$noteStoreTrans = new THttpClient(noteStoreHost, noteStorePort, noteStoreUrl . $_SESSION['shardId'], noteStoreProto);
			$noteStoreProt = new TBinaryProtocol($noteStoreTrans);
			$noteStore = new NoteStoreClient($noteStoreProt, $noteStoreProt);
			$notebooks = $noteStore->listNotebooks($_SESSION['accessToken']);
			usort($notebooks, "notebookSorter");
		} catch (edam_error_EDAMSystemException $e) {
			if (isset(edam_error_EDAMErrorCode::$__names[$e->errorCode])) {
				raiseAppError(edam_error_EDAMErrorCode::$__names[$e->errorCode] . ": " . $e->parameter);
			} else {
				raiseAppError($e->getCode() . ": " . $e->getMessage());
			}
		} catch (edam_error_EDAMUserException $e) {
			if ($e->errorCode == $GLOBALS['edam_error_E_EDAMErrorCode']['AUTH_EXPIRED']) {
				resetSession();
				getRequestToken();
				raiseAppError("Authorization expired. You must re-authorize access with Evernote.");
			} else {
				if (isset(edam_error_EDAMErrorCode::$__names[$e->errorCode])) {
					raiseAppError(edam_error_EDAMErrorCode::$__names[$e->errorCode] . ": " . $e->parameter);
				} else {
					raiseAppError($e->getCode() . ": " . $e->getMessage());
				}
			}
		} catch (edam_error_EDAMNotFoundException $e) {
			if (isset(edam_error_EDAMErrorCode::$__names[$e->errorCode])) {
				raiseAppError(edam_error_EDAMErrorCode::$__names[$e->errorCode] . ": " . $e->parameter);
			} else {
				raiseAppError($e->getCode() . ": " . $e->getMessage());
			}
		} catch (Exception $e) {
			raiseError("Unexpected error: " . $e->getMessage());
		}
	}
	return $notebooks;
}

function notebookSorter($nb1, $nb2) {
	if ($nb1->name == $nb2->name)
		return 0;
	return ($nb1->name < $nb2->name) ? -1 : 1;
}

?>